--[[
    OneCompanion, a cool companion bag for World of Warcraft
    Copyright (C) 2010 Arnaud Dovi (ad@heapoverflow.com)

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
]]

--[[
$Rev:: 0                     $:  Revision of last commit
$Author:: arnaud             $:  Author of last commit
$Date:: 2012-09-02 22:37:24 #$:  Date of last commit
$WoW:: 5.0.5.16030           $:  Client of the last tests
]]

if not (select(4,GetBuildInfo()) >= 30000) then return end
local MINOR_VERSION = tonumber(("$Revision: 38 $"):match("%d+"))
if MINOR_VERSION > _G.OneCompanion_MINOR_VERSION then _G.OneCompanion_MINOR_VERSION = MINOR_VERSION end

OneCompanionFrames, OneCompanionButtons, OneCompanionMaxHeight = {}, {}, 0
local L = LibStub("AceLocale-3.0"):GetLocale("OneCompanion")

function OneCompanionFrames:build()
    local self, fra, opt = OneCompanion, OneCompanionFrames, OneCompanionOptions
    local breanni = CreateFrame("Button", "OneCompanionBag", UIParent, "BankItemButtonGenericTemplate")
    local texture = breanni:CreateTexture("OneCompanionBagTexture")
    local base = CreateFrame("Frame", "OneCompanionBaseFrame", UIParent)
    local index = CreateFrame("Frame", "OneCompanionIndexFrame", base)
    local scrollindex = CreateFrame("ScrollFrame", "OneCompanionScrollFrame", index)
    local grip = CreateFrame("Button", "OneCompanionGrip", index)
    local slider = CreateFrame("Slider", "OneCompanionIndexSlider", index)
    local child = CreateFrame("Frame", "OneCompanionIndexChild", scrollindex)
    local footer = CreateFrame("Frame", nil, base)
    local footerText = footer:CreateFontString(nil, nil, "GameFontNormal")
    local footerRev = footer:CreateFontString(nil, nil, "GameFontNormal")
    local cfgButton = CreateFrame("Button", nil, footer)
    local modButton = CreateFrame("Button", nil, footer)
    local model = CreateFrame("Frame", "OneCompanionModelFrame", base)
    local modelindex = CreateFrame("PlayerModel", "OneCompanionModelIndexFrame", model)
    local mgrip = CreateFrame("Button", "OneCompanionModelGrip", model)
    local sliderBackdrop = {
        bgFile = [[Interface\Buttons\UI-SliderBar-Background]],
        edgeFile = [[Interface\Buttons\UI-SliderBar-Border]],
        tile = true, tileSize = 8, edgeSize = 8,
        insets = { left = 3, right = 3, top = 3, bottom = 3 }
        }
    texture:SetAllPoints(breanni)
    texture:SetTexture([[Interface\AddOns\OneCompanion\textures\breanni]])
    breanni:SetPoint(self.db.profile.sizes.breannipt, UIParent, self.db.profile.sizes.breannirpt, self.db.profile.sizes.breannix, self.db.profile.sizes.breanniy)
    breanni:SetID(1)
    base:SetHeight(self.db.profile.sizes.h)
    base:SetWidth(self.db.profile.sizes.w)
    base:SetPoint(self.db.profile.sizes.pt, UIParent, self.db.profile.sizes.rpt, self.db.profile.sizes.x, self.db.profile.sizes.y)
    model:SetHeight(self.db.profile.sizes.mh)
    model:SetWidth(self.db.profile.sizes.mw)
    model:SetPoint("TOPLEFT", base, "TOPRIGHT", 0, 0)
    footer:SetHeight(30)
    footer:SetWidth(self.db.profile.sizes.w)
    footer:SetPoint("BOTTOMLEFT", base, "BOTTOMLEFT", 0, 0)
    footer:SetPoint("BOTTOMRIGHT", base, "BOTTOMRIGHT", 0, 0)
    scrollindex:SetScrollChild(child)
    index:SetWidth(self.db.profile.sizes.w)
    index:SetPoint("BOTTOMLEFT", footer, "TOPLEFT", 0, 0)
    index:SetPoint("BOTTOMRIGHT", footer, "TOPRIGHT", 0, 0)
    index:SetPoint("TOPLEFT", base, "TOPLEFT", 0, 0)
    index:SetPoint("TOPRIGHT", base, "TOPRIGHT", 0, 0)
    modelindex:SetPoint("BOTTOMLEFT", model, "BOTTOMLEFT", 5, 5)
    modelindex:SetPoint("BOTTOMRIGHT", model, "BOTTOMRIGHT", -5, 5)
    modelindex:SetPoint("TOPLEFT", model, "TOPLEFT", 5, -5)
    modelindex:SetPoint("TOPRIGHT", model, "TOPRIGHT", -5, -5)
    scrollindex:SetPoint("TOPLEFT", self.db.profile.sizes.borderpad, - self.db.profile.sizes.borderpad)
    scrollindex:SetPoint("TOPRIGHT", - self.db.profile.sizes.borderpad, - self.db.profile.sizes.borderpad)
    scrollindex:SetPoint("BOTTOMLEFT", self.db.profile.sizes.borderpad, self.db.profile.sizes.borderpad)
    scrollindex:SetPoint("BOTTOMRIGHT", - self.db.profile.sizes.borderpad, self.db.profile.sizes.borderpad)
    child:SetWidth(scrollindex:GetWidth())
    slider:SetOrientation("VERTICAL")
--	slider:SetHitRectInsets(0, -10, -10, -10)
    slider:SetBackdrop(sliderBackdrop)
    slider:SetWidth(8)
    slider:SetThumbTexture([[Interface\Buttons\UI-SliderBar-Button-Vertical]])
    slider:SetFrameStrata("FULLSCREEN_DIALOG")
--	slider:SetPoint("TOPLEFT", index, "TOPRIGHT", 5, 0)
--	slider:SetPoint("BOTTOMLEFT", index, "BOTTOMRIGHT", 5, 0)
    slider:SetMinMaxValues(0, 1)
    slider:SetValueStep(0.001)
    slider:SetValue(0)
    slider:SetScript("OnValueChanged", function(this)
        local max_ = child:GetHeight() - scrollindex:GetHeight()
        local val = this:GetValue() * max_
        if math.abs(scrollindex:GetVerticalScroll() - val) < 1 then
            return
        end
        scrollindex:SetVerticalScroll(val)
    end)
    grip:SetNormalTexture([[Interface\AddOns\OneCompanion\textures\grip]])
    grip:SetHighlightTexture([[Interface\AddOns\OneCompanion\textures\grip]])
    grip:SetWidth(16)
    grip:SetHeight(16)
    grip:SetScript("OnMouseDown", function() base:StartSizing() grip:SetScript("OnUpdate", function() fra:SetAnchors(base) opt:ToggleButtonScale(nil, nil, nil, nil) end) end)
    grip:SetScript("OnMouseUp", function() base:SetScript("OnSizeChanged", nil) base:StopMovingOrSizing() grip:SetScript("OnUpdate", nil) fra:SetAnchors(base) end)
    grip:SetPoint("BOTTOMRIGHT", index, "BOTTOMRIGHT", -1, 1)
    grip:SetFrameLevel(30)
    mgrip:SetNormalTexture([[Interface\AddOns\OneCompanion\textures\grip]])
    mgrip:SetHighlightTexture([[Interface\AddOns\OneCompanion\textures\grip]])
    mgrip:SetWidth(16)
    mgrip:SetHeight(16)
    mgrip:SetScript("OnMouseDown", function() model:StartSizing() end)
    mgrip:SetScript("OnMouseUp", function() model:SetScript("OnSizeChanged", nil) model:StopMovingOrSizing() fra:SetModelAnchors(model) end)
    mgrip:SetPoint("BOTTOMRIGHT", model, "BOTTOMRIGHT", -1, 1)
    mgrip:SetFrameLevel(30)
    footerRev:SetPoint("BOTTOMRIGHT", footer, "BOTTOMRIGHT", -5, 5)
    footerRev:SetText("r|cff7a7a7a" .. _G.OneCompanion_MINOR_VERSION .. "|r")
    footerText:SetText("One|cffffcc00Companion|r")
    footerText:SetJustifyH("LEFT")
    footerText:SetTextColor(1, 1, 1, 0.95)
    local f, s, p = footerRev:GetFont()
    footerRev:SetFont(f, 8, p)
    cfgButton:SetNormalTexture([[Interface\Icons\Ability_Repair]])
    cfgButton:SetHighlightTexture([[Interface\Buttons\ButtonHilight-Square]])
    cfgButton:SetPoint("LEFT", footer, "LEFT", 7, 0)
    cfgButton:SetWidth(20)
    cfgButton:SetHeight(20)
    modButton:SetNormalTexture([[Interface\Icons\INV_Misc_Spyglass_02]])
    modButton:SetHighlightTexture([[Interface\Buttons\ButtonHilight-Square]])
    modButton:SetPoint("LEFT", cfgButton, "RIGHT", 5, 0)
    modButton:SetWidth(20)
    modButton:SetHeight(20)
    base:EnableMouse(true)
    index:EnableMouse(true)
    scrollindex:EnableMouse(true)
    child:EnableMouse(true)
    footer:EnableMouse(true)
    model:EnableMouse(true)
    modelindex:EnableMouse(true)
    base:SetResizable(true)
    index:SetResizable(true)
    modelindex:SetResizable(true)
    footer:SetResizable(true)
    model:SetResizable(true)
    base:SetMinResize(59, 68)
    model:SetMinResize(40, 40)
    breanni:SetScript("OnClick", OneCompanion.ToggleShowHide)
    cfgButton:SetScript("OnClick", OneCompanion.OpenConfig)
    modButton:SetScript("OnClick", OneCompanion.OpenModel)

    fra.base = base
    fra.index = index
    fra.scrollindex = index
    fra.child = child
    fra.slider = slider
    fra.footer = footer
    fra.grip = grip
    fra.cfgButton = cfgButton
    fra.modButton = modButton
    fra.breanni = breanni
    fra.footerText = footerText
    fra.footerRev = footerRev
    fra.model = model
    fra.modelindex = modelindex
    fra.mgrip = mgrip

    base:Hide()
    model:Hide()

    opt:ToggleBackdrop(nil, nil)
    opt:ToggleShowTooltips(nil, nil, nil)
    opt:SetColor(nil, nil, nil, nil, nil)
    opt:ToggleMainFrameClamp(nil)
    opt:ToggleModelFrameClamp(nil)
    opt:ToggleShowGrip(nil)
    opt:ToggleShowModelGrip(nil)
    opt:ToggleLockBreanni(nil)
    fra:buildButtons()
    opt:ToggleShowTooltips(nil)
    opt:ToggleLockBag(nil)
    opt:ToggleButtonScale(nil, nil, nil, nil)
    opt:ToggleBreanniScale(nil, nil)
    opt:ToggleStrata(nil, nil)
end


function OneCompanionFrames:ShowSlider()
    local self , fra = OneCompanion, OneCompanionFrames
    local h, m = fra.scrollindex:GetHeight(), OneCompanionMaxHeight
    if m > h then
        fra.slider:ClearAllPoints()
        if fra.model:IsVisible() then
            fra.slider:SetPoint("TOPRIGHT", fra.index, "TOPLEFT", -5, 0)
            fra.slider:SetPoint("BOTTOMRIGHT", fra.index, "BOTTOMLEFT", -5, 0)
        else
            fra.slider:SetPoint("TOPLEFT", fra.index, "TOPRIGHT", 5, 0)
            fra.slider:SetPoint("BOTTOMLEFT", fra.index, "BOTTOMRIGHT", 5, 0)
        end
        fra.slider:Show()
    else
        fra.slider:Hide()
        fra.slider:SetValue(0)
    end
    fra.child:SetHeight(m)
end

function OneCompanionFrames:SetAnchors(f)
    local self , fra = OneCompanion, OneCompanionFrames
    if f then
        self.db.profile.sizes.pt, _, self.db.profile.sizes.rpt, self.db.profile.sizes.x, self.db.profile.sizes.y = f:GetPoint()
        self.db.profile.sizes.w = f:GetWidth()
        self.db.profile.sizes.h = f:GetHeight()
        fra.footer:SetWidth(self.db.profile.sizes.w)
        fra.index:SetWidth(self.db.profile.sizes.w)
        fra.child:SetWidth(self.db.profile.sizes.w)
        fra.footer:SetPoint("BOTTOMLEFT", fra.base, "BOTTOMLEFT", 0, 0)
        fra.footer:SetPoint("BOTTOMRIGHT", fra.base, "BOTTOMRIGHT", 0, 0)
        fra.index:SetPoint("BOTTOMLEFT", fra.footer, "TOPLEFT", 0, 0)
        fra.index:SetPoint("BOTTOMRIGHT", fra.footer, "TOPRIGHT", 0, 0)
        fra.index:SetPoint("TOPLEFT", fra.base, "TOPLEFT", 0, 0)
        fra.index:SetPoint("TOPRIGHT", fra.base, "TOPRIGHT", 0, 0)
        fra.model:SetPoint("TOPLEFT", fra.base, "TOPRIGHT", 0, 0)
    end
end

function OneCompanionFrames:SetModelAnchors(f)
    local self , fra = OneCompanion, OneCompanionFrames
    if f then
        self.db.profile.sizes.mw = f:GetWidth()
        self.db.profile.sizes.mh = f:GetHeight()
        fra.model:ClearAllPoints()
        fra.model:SetPoint("TOPLEFT", fra.base, "TOPRIGHT", 0, 0)
        fra.modelindex:SetPoint("BOTTOMLEFT", fra.model, "BOTTOMLEFT", 5, 5)
        fra.modelindex:SetPoint("BOTTOMRIGHT", fra.model, "BOTTOMRIGHT", -5, 5)
        fra.modelindex:SetPoint("TOPLEFT", fra.model, "TOPLEFT", 5, -5)
        fra.modelindex:SetPoint("TOPRIGHT", fra.model, "TOPRIGHT", -5, -5)
    end
end

function OneCompanionFrames:SetBreanniAnchors(f)
    local self , fra = OneCompanion, OneCompanionFrames
    if f then
        self.db.profile.sizes.breannipt, _, self.db.profile.sizes.breannirpt, self.db.profile.sizes.breannix, self.db.profile.sizes.breanniy = f:GetPoint()
        self.db.profile.sizes.breannix = self.db.profile.sizes.breannix * self.db.profile.sizes.bsc
        self.db.profile.sizes.breanniy = self.db.profile.sizes.breanniy * self.db.profile.sizes.bsc
    end
end

function OneCompanionFrames:buildButtons()
    local self, fra, btn = OneCompanion, OneCompanionFrames, OneCompanionButtons
    local mount, critter = GetNumCompanions("MOUNT"), GetNumCompanions("CRITTER")
    for i, j in ipairs(btn) do
        j:Hide()
    end
    for i = 1, mount + critter do
        local slot = CreateFrame("CheckButton", "OneCompanionSlot" .. i, fra.child, "BankItemButtonGenericTemplate")
        local cool = CreateFrame("Cooldown", "OneCompanionSlot" .. i .. "Cooldown", slot, "CooldownFrameTemplate")
        local texture, type, petID = slot:CreateTexture("OneCompanionTexture" .. i), nil, nil
        if i <= mount then type = "MOUNT" petID = i
        else type = "CRITTER" petID = i - mount end
        local creatureID, creatureName, spellID, icon, active = GetCompanionInfo(type, petID)
        slot.cool, slot.type, slot.petID, slot.creatureID, slot.creatureName, slot.spellID, slot.active = cool, type, petID, creatureID, creatureName, spellID, active
        cool:SetAllPoints(slot)
        cool:SetAlpha(0.8)
        texture:SetAllPoints(slot)
        texture:SetTexture(icon)
        slot:SetID(i)
        btn[i] = slot
        slot:SetScript("OnClick", function()
            if IsModifiedClick("CHATLINK") then
                if MacroFrame and MacroFrame:IsShown() then
                    local spellName = GetSpellInfo(spellID)
                    ChatEdit_InsertLink(spellName)
                else
                    local spellLink = GetSpellLink(spellID)
                    ChatEdit_InsertLink(spellLink)
                end
            elseif IsControlKeyDown() then
                fra.model:Show()
                fra.ShowSlider()
                fra.modelindex:SetCreature(creatureID)
            elseif SpellCanTargetItem() then
                self:Print("Will be implemented when Blizzard will. Yet you can enchant mounts only when they are in you inventory before learning them.")
            else
                local creatureID, creatureName, spellID, icon, active = GetCompanionInfo(type, petID)
                if active then
                    DismissCompanion(type, petID)
                    PlaySound("igMainMenuOptionCheckBoxOn")
                else
                    CallCompanion(type, petID)
                    PlaySound("igMainMenuOptionCheckBoxOff")
                end
            end
        end)
    end
end

function OneCompanionFrames:UpdateCooldowns()
    local btn = OneCompanionButtons
    for i, j in ipairs(btn) do
        local start, duration, enable = GetCompanionCooldown(btn[i].type, btn[i].petID)
        CooldownFrame_SetTimer(btn[i].cool, start, duration, enable)
    end
end

function OneCompanionFrames:OnRotateModel()
    local self, endx, endy = OneCompanionFrames.modelindex, GetCursorPosition()
    self.rot = (endx - self.startx) / 34 + self:GetFacing()
    self:SetRotation(self.rot)
    self.startx, self.starty = GetCursorPosition()
end
